package com.odyssey.enemies;

import org.anddev.andengine.engine.camera.BoundCamera;
import org.anddev.andengine.entity.Entity;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTile;
import org.anddev.andengine.entity.primitive.Line;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import android.util.Log;
//import java.lang.Math;

import com.odyssey.common.Circle;
import com.odyssey.common.Coordinate;
import com.odyssey.common.Definitions;
import com.odyssey.common.Direction;
import com.odyssey.player.PlayerData;


public class Enemy extends Entity
{
  protected Scene eScene;
  protected BoundCamera eCam;
  protected TiledTextureRegion eTexture;
  protected Coordinate eLoc;
  protected Circle eCol;
  protected Direction facing;
  protected Direction oldFace;
  protected int health;
  protected int hpLeft;
  protected boolean alive;
  private boolean hitSoundFlag;
  private boolean isBoss;
  protected Line hpBar;
  protected AnimatedSprite eSprite;
  
  //constructor ***********************************************************
  public Enemy(final int x, final int y, BoundCamera cam, final TiledTextureRegion texture, Scene inScene, int hp)
  {
    
    super(0,0); //entity init
    eLoc = new Coordinate();
    eLoc.x = x;
    eLoc.y = y;
    eCam = cam;
    eTexture = texture;
    eScene = inScene;
    health = hp;
    hpLeft = hp;
    alive = true;
    facing = Direction.RIGHT;
    oldFace = Direction.RIGHT;
    setHitSoundFlag(false);
 
    eSprite = new AnimatedSprite(eLoc.x, eLoc.y, eTexture)
    {
      @Override
      public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY)
      {
        if(pSceneTouchEvent.isActionDown())
        {
          setHitSoundFlag(true);
          hpLeft -= PlayerData.getDamage();
          float hpx = ((float)hpLeft/(float)health);
          if (hpLeft <= 0)
          {
            death();
          }
          hpBar.setPosition(eLoc.x -5, eLoc.y - 5, eLoc.x - 5 + Definitions.hpbarsize, eLoc.y - 5);
          hpBar.setScaleX(hpx);
          Log.v("GEISHA", "I WAS TOUCHED "+hpx);
        }
        return false;
      }
    };
    eScene.registerTouchArea(eSprite);
    
    eCol = new Circle((int) (eSprite.getWidth()/2),(int) (eSprite.getHeight()/2), 
    		eSprite.getWidth() > eSprite.getHeight() ? 
           (int) (eSprite.getWidth()/2) : (int) (eSprite.getHeight()/2));
    eCol.x = eCol.x + eLoc.x;
    eCol.y = eCol.y + eLoc.y;
    eScene.attachChild(eSprite);
    hpBar = new Line(eLoc.x - 5, eLoc.y - 5, eLoc.x - 5 + Definitions.hpbarsize, eLoc.y - 5, 3);
    hpBar.setColor(0f, 1f, 0f);
    eScene.attachChild(hpBar);
    
  }
  
  //miscellaneous**************************************************
  public void death()
  {
    alive = false;
    //eScene.detachChild(hpBar);
    hpBar.setVisible(false);
    //eScene.detachChild(eSprite);
    eSprite.setVisible(false);
  }

  
  
  
  //getters & setters*****************************************************
  
  public Direction getDir()
  {
    return facing;
  }
  
  public Coordinate getCoor()
  {
    return eLoc;
  }
  
  public Circle getCircle()
  {
    return eCol;
  }
  
  public boolean isAlive()
  {
    return alive;
  }
  
  public boolean isHitSoundFlag()
  {
    return hitSoundFlag;
  }

  public void setHitSoundFlag(boolean hitSoundFlag)
  {
    this.hitSoundFlag = hitSoundFlag;
  }

  public boolean isBoss()
  {
    return isBoss;
  }

  public void setBoss(boolean isBoss)
  {
    this.isBoss = isBoss;
  }

  public void setScale(float x)
  {
    eSprite.setScale(x);
  }
  
  //collision & falling stuff*****************************************************
  
  public boolean collision(TMXTile left, TMXTile right)
  {
    //if die, set animation and alive = false
    //if collide with player or player weap, hp -= 50;

    if (this.facing.equals(Direction.LEFT))
    {
      if (left == null && this.eLoc.x == 0)
      {
        return true;
      }
      else if (left == null)
      {
        return false;
      }
      else if (left.getGlobalTileID() == 124) 
      {
        return true;
      }
      else 
      {
        return false;
      }
    }
    else 
    {
      if (right == null && this.eLoc.x == Definitions.mapWidth)
      {
        return true;
      }
      else if (right == null)
      {
        return false;
      }
      else if (right.getGlobalTileID() == 124) 
      {
        return true;
      }
      else 
      {
        return false;
      }
    }
  }
  
  public boolean fall(TMXTile below)
  {
    //check if there is block underneath, otherwise gravity fall
    if (below == null)
    {
      return false;
    }
    else if (below.getGlobalTileID() == 124)
    {
      return false;
    }
    else 
    {
      //Log.v("EECS285 PROJECT4", "belowTileId: " +below.getGlobalTileID());
      return true;
    }
  }

  //artifical intelligence stuff*************************************
  public void seekPlayer() 
  {
    //change orientation based on if detect player nearby

  }
  
  
  
  //update loop************************************************************
  
  
  public void updateAnimation()
  {
    if (oldFace != facing)
    {
      if (facing == Direction.RIGHT)
        eSprite.animate(new long[]{200, 200, 200, 200, 200, 200}, 12, 17, true);
      else if (facing == Direction.LEFT)
        eSprite.animate(new long[]{200, 200, 200, 200, 200, 200}, 0, 5, true);
      oldFace = facing;
    }

  }
  
  public void enemyUpdate(TMXTile left, TMXTile right, TMXTile above, TMXTile below, TMXTile fall)
  {
    if (alive == false) return;
    //if camera does not overlap, do not move enemy
    //if (camera.x < mLoc.x) return;
    //check for collision with background or player
    
    //x-bounds of camera
    //int lL = (int) (eCam.getCenterX() - eCam.getWidth()/2); 
    //int rL = (int) (eCam.getCenterX() + eCam.getWidth()/2);
    int lL = (int) (eCam.getCenterX() - eCam.getWidth()); 
    int rL = (int) (eCam.getCenterX() + eCam.getWidth());
    //Log.v("TESTING1", "cam center "+eCam.getCenterX()+" cam width "+eCam.getWidth());
    //Log.v("TESTING", "cam maxX "+lL+" "+rL+" "+eLoc.x);
    
    //if enemy is currently within camera, move in direction facing
    if(eLoc.x < rL && eLoc.x > lL)
    {
      if (fall(fall) && !fall(below))
      {
        if (facing == Direction.LEFT) facing = Direction.RIGHT;
        else if (facing == Direction.RIGHT) facing = Direction.LEFT; 
      }
      if(fall(below))
      {
       eLoc.y += Definitions.velocity;
       eCol.y += Definitions.velocity;
       if (eCol.y+(eSprite.getHeight()/2) <= 0)
       { 
         death();
       }
      } 
      
      if(facing == Direction.LEFT)
      {
        if (collision(left,right)) facing = Direction.RIGHT;
        else 
        {
          eLoc.x -= Definitions.velocity;
          eCol.x -= Definitions.velocity;
        }
        //move left
      }
      
      if(facing == Direction.RIGHT)
      {
        if (collision(left,right)) facing = Direction.LEFT;
        else 
        {
          eLoc.x += Definitions.velocity;
          eCol.x += Definitions.velocity;
        }
        //move right
      }
      
      //float hpx = (hpleft/health)*Definitions.hpbarsize;
      //Log.v("HPX IS", ""+hpx);
      hpBar.setPosition(eLoc.x - 5, eLoc.y - 5, eLoc.x - 5 + Definitions.hpbarsize , eLoc.y - 5);
      eSprite.setPosition(eLoc.x, eLoc.y);
    }
    else
    {
      return;
    }

  }
  
  

}
